/******************************************************************************
 * Copyright (C) 2009 Low Heng Sin                                            *
 * Copyright (C) 2009 Idalica Corporation                                     *
 * This program is free software; you can redistribute it and/or modify it    *
 * under the terms version 2 of the GNU General Public License as published   *
 * by the Free Software Foundation. This program is distributed in the hope   *
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.           *
 * See the GNU General Public License for more details.                       *
 * You should have received a copy of the GNU General Public License along    *
 * with this program; if not, write to the Free Software Foundation, Inc.,    *
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.                     *
 *****************************************************************************/
package org.compiere.apps.form;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.VetoableChangeListener;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Vector;
import java.util.logging.Level;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;

import org.adempiere.exceptions.AdempiereException;
import org.adempiere.plaf.AdempierePLAF;
import org.compiere.apps.ADialog;
import org.compiere.apps.ProcessCtl;
import org.compiere.apps.StatusBar;
import org.compiere.grid.ed.VCheckBox;
import org.compiere.grid.ed.VDate;
import org.compiere.grid.ed.VLookup;
import org.compiere.minigrid.MiniTable;
import org.compiere.model.MColumn;
import org.compiere.model.MLookup;
import org.compiere.model.MPInstance;
import org.compiere.model.MProcess;
import org.compiere.model.MLookupFactory;
import org.compiere.model.X_A_Asset;
import org.compiere.plaf.CompiereColor;
import org.compiere.process.ProcessInfo;
import org.compiere.process.ProcessInfoParameter;
import org.compiere.swing.CPanel;
import org.compiere.swing.CTextField;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg;
import org.compiere.util.Trx;
import org.compiere.util.Util;

public class VAssetTransfer //extends AssetTransfer
	implements FormPanel, ActionListener, TableModelListener, VetoableChangeListener
{
	private CPanel panel = new CPanel();
	public DecimalFormat format = DisplayType.getNumberFormat(DisplayType.Amount);
	/**	Logger			*/
	public static CLogger log = CLogger.getCLogger(VAssetTransfer.class);
	public int  m_C_BPartner_ID ;
	public int  m_C_BPartner2_ID;
	public int	m_New_A_Location_ID = 0;
	public int	total;
	public Timestamp transferDate = null;
	public int  m_AD_Org_ID = 0;
	public String repName = "A_Asset_Form_OS2";
	
	/**
	 *	Initialize Panel
	 *  @param WindowNo window
	 *  @param frame frame
	 */
	public void init (int WindowNo, FormFrame frame)
	{
		m_WindowNo = WindowNo;
		m_frame = frame;
		Env.setContext(Env.getCtx(), m_WindowNo, "IsSOTrx", "Y");   //  defaults to no
		try
		{
			dynInit();
			jbInit();
			calculate();
			frame.getContentPane().add(mainPanel, BorderLayout.CENTER);
			frame.getContentPane().add(statusBar, BorderLayout.SOUTH);
		}
		catch(Exception e)
		{
			log.log(Level.SEVERE, "", e);
		}
	}	//	init

	/**	Window No			*/
	private int         m_WindowNo = 0;
	/**	FormFrame			*/
	private FormFrame 	m_frame;

	private CPanel 			mainPanel = new CPanel();
	private BorderLayout 	mainLayout = new BorderLayout();
	private CPanel 			parameterPanel = new CPanel();
	private CPanel 			transferPanel = new CPanel();
	private GridBagLayout 	parameterLayout = new GridBagLayout();
	private JLabel 			bpartnerLabel = new JLabel();
	private VLookup 		bpartnerSearch = null;
	private JLabel 			bpartner2Label = new JLabel();
	private VLookup 		bpartner2Search = null;
	private MiniTable 		assetTable = new MiniTable();
	private CPanel 			assetPanel = new CPanel();
	private JLabel 			assetLabel = new JLabel();
	private BorderLayout 	assetLayout = new BorderLayout();
	private JLabel 			assetInfo = new JLabel();
	private JScrollPane 	assetScrollPane = new JScrollPane();
	private GridBagLayout 	transferLayout = new GridBagLayout();
	private JLabel 			differenceLabel = new JLabel();
	private CTextField 		differenceField = new CTextField();
	private JButton 		transferButton = new JButton();
	private StatusBar 		statusBar = new StatusBar();
	private JLabel 			dateLabel = new JLabel();
	private VDate 			dateField = new VDate();
	private JLabel 			organizationLabel = new JLabel();
	private VLookup 		organizationPick = null;
	private JLabel 			descriptionLabel = new JLabel();
	private CTextField 		descriptionField = new CTextField();
	private VLookup 		docNoSearch = null;
	private JLabel 			docNoLabel = new JLabel();
	//---Aslanbek
	private VCheckBox		selectAll = new VCheckBox();
	private JLabel			selectAllLabel = new JLabel();
	private JLabel			locationLabel = new JLabel();
	private VLookup			locationSearch = null;
	//---
	/**
	 *  Static Init
	 *  @throws Exception
	 */
	private void jbInit() throws Exception
	{
		CompiereColor.setBackground(panel);
		//
		mainPanel.setLayout(mainLayout);
		dateLabel.setText(Msg.translate(Env.getCtx(), "MovementDate"));
		dateLabel.setToolTipText(Msg.translate(Env.getCtx(), "MovementDate"));
		parameterPanel.setLayout(parameterLayout);
		transferPanel.setLayout(transferLayout);
		bpartnerLabel.setText("Ответственное лицо:"); //bpartnerLabel.setText(Msg.translate(Env.getCtx(), "C_BPartnerSR_ID"));
		bpartner2Label.setText("Переместить на:");
		assetLabel.setRequestFocusEnabled(false);
		assetLabel.setText(" " + Msg.translate(Env.getCtx(), "A_Asset_ID"));
		assetPanel.setLayout(assetLayout);
		assetInfo.setHorizontalAlignment(SwingConstants.RIGHT);
		assetInfo.setHorizontalTextPosition(SwingConstants.RIGHT);
		assetInfo.setText(".");
		differenceLabel.setText(Msg.getMsg(Env.getCtx(), "Difference"));
		differenceField.setBackground(AdempierePLAF.getFieldBackground_Inactive());
		differenceField.setEditable(false);
		differenceField.setText("0");
		differenceField.setColumns(8);
		differenceField.setHorizontalAlignment(SwingConstants.RIGHT);
		transferButton.setText(Msg.getMsg(Env.getCtx(), "Process"));
		transferButton.addActionListener(this);
		descriptionLabel.setText(Msg.getMsg(Env.getCtx(), "Description"));
		descriptionField.setColumns(20);
		docNoLabel.setText(Msg.getMsg(Env.getCtx(), "DocumentNo"));
		//descriptionField.setBackground(AdempierePLAF.getFieldBackground_Inactive());
		assetScrollPane.setPreferredSize(new Dimension(400, 200));
		mainPanel.add(parameterPanel, BorderLayout.NORTH);
		//-----Aslanbek
		selectAllLabel.setText("Выбрать все"); ///selectAllLabel.setText(Msg.getMsg(Env.getCtx(), "Select All"));
		selectAll.addActionListener(this);
		locationLabel.setText("Местоположение :");
		locationSearch.addActionListener(this);
		//---
		//org filter
		organizationLabel.setText(Msg.translate(Env.getCtx(), "AD_Org_ID"));
		
		parameterPanel.add(organizationLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
				,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5,5,5,5), 0, 0));
		parameterPanel.add(organizationPick, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0
				,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5,5,5,5), 0, 0));
		parameterPanel.add(bpartnerLabel, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0
			,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		parameterPanel.add(bpartnerSearch, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0
			,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
		parameterPanel.add(dateLabel, new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0
			,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		parameterPanel.add(dateField, new GridBagConstraints(5, 0, 1, 1, 0.0, 0.0
			,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
		parameterPanel.add(selectAllLabel, new GridBagConstraints(6, 0, 1, 1, 0.0, 0.0, 
				GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 25, 5, 0), 0, 0));
		parameterPanel.add(selectAll, new GridBagConstraints(7, 0, 1, 1, 0.0, 0.0, 
				GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(9, 5, 5, 5), 0, 0));
		
		mainPanel.add(transferPanel, BorderLayout.SOUTH);
		
		transferPanel.add(bpartner2Label, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
				,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		transferPanel.add(bpartner2Search, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0
				,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
		transferPanel.add(descriptionLabel, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0
				,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		transferPanel.add(descriptionField, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0
				,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
		
		transferPanel.add(differenceLabel, new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0,
				GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 0), 0, 0));
		transferPanel.add(differenceField, new GridBagConstraints(5, 0, 1, 1, 0.0, 0.0
				,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
		//---Aslanbek
		transferPanel.add(docNoLabel, new GridBagConstraints(6, 0, 1, 1, 0.0, 0.0
				,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
		transferPanel.add(docNoSearch, new GridBagConstraints(7, 0, 1, 1, 0.0, 0.0
				,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
		transferPanel.add(locationLabel, new GridBagConstraints(8, 0, 1, 1, 0.0, 0.0,
				GridBagConstraints.EAST, new GridBagConstraints().NONE, new Insets(5, 25, 5, 5), 0, 0));
		transferPanel.add(locationSearch, new GridBagConstraints(9, 0, 1, 1, 0.0, 0.0,
				GridBagConstraints.EAST, new GridBagConstraints().NONE, new Insets(5, 0, 5, 5), 0, 0));
		//--
		transferPanel.add(transferButton, new GridBagConstraints(10, 0, 1, 1, 0.0, 0.0
				,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(5, 20, 5, 5), 0, 0));
		assetPanel.add(assetLabel, BorderLayout.NORTH);
		assetPanel.add(assetInfo, BorderLayout.SOUTH);
		assetPanel.add(assetScrollPane, BorderLayout.CENTER);
		assetScrollPane.getViewport().add(assetTable, null);
		mainPanel.add(assetScrollPane, BorderLayout.CENTER);
	}   //  jbInit

	/**
	 * 	Dispose
	 */
	public void dispose()
	{
		if (m_frame != null)
			m_frame.dispose();
		m_frame = null;
	}	//	dispose

	/**
	 *  Dynamic Init (prepare dynamic fields)
	 *  @throws Exception if Lookups cannot be initialized
	 */
	public void dynInit() throws Exception
	{

		// Organization filter selection
		int AD_Column_ID = 839; //C_Period.AD_Org_ID (needed to allow org 0)
		MLookup lookupOrg = MLookupFactory.get(Env.getCtx(), m_WindowNo, 0, AD_Column_ID, DisplayType.TableDir);
		organizationPick = new VLookup("AD_Org_ID", true, false, true, lookupOrg);
		organizationPick.setValue(Env.getAD_Org_ID(Env.getCtx()));
		m_AD_Org_ID=Env.getAD_Org_ID(Env.getCtx());
		organizationPick.addVetoableChangeListener(this);

		//  BPartner (Agent)
		AD_Column_ID = 14096;        //  A_Asset.C_BPartnerSR_ID
		MLookup lookupBP = MLookupFactory.get (Env.getCtx(), m_WindowNo, 0, AD_Column_ID, DisplayType.Table);
		bpartnerSearch = new VLookup("C_BPartnerSR_ID", true, false, true, lookupBP);
		bpartnerSearch.addVetoableChangeListener(this);

		//  BPartner2 (Agent)
		MLookup lookupBP2 = MLookupFactory.get (Env.getCtx(), m_WindowNo, 0, AD_Column_ID, DisplayType.Table);
		bpartner2Search = new VLookup("C_BPartnerSR2_ID", true, false, true, lookupBP2);
		bpartner2Search.addVetoableChangeListener(this);
		
		//  Status
		statusBar.setStatusLine(Msg.translate(Env.getCtx(), "Status"));
		statusBar.setStatusDB("");

		//  Transfer Date 
		dateField.setValue(Env.getContextAsDate(Env.getCtx(), "#Date"));
		dateField.setMandatory(true);
		transferDate = (Timestamp)Env.getContextAsDate(Env.getCtx(), "#Date");
		dateField.addVetoableChangeListener(this);
		
		//  Document Number  A_InternalMovement.DocumentNo
		AD_Column_ID = MColumn.getColumn_ID("A_InternalMovement", "DocumentNo");


		MLookup lookupDN = MLookupFactory.get (Env.getCtx(), m_WindowNo, 0, AD_Column_ID, DisplayType.Table);
		docNoSearch = new VLookup("DocumentNo", false, false, true, lookupDN);
		docNoSearch.addVetoableChangeListener(this);
		
		//Asset(s) location
		AD_Column_ID = 1003725;
		MLookup lookupLocation = MLookupFactory.get(Env.getCtx(), m_WindowNo, 0, AD_Column_ID, DisplayType.TableDir);
		locationSearch = new VLookup("A_Location_ID", false, false, true, lookupLocation);
		
	}   //  dynInit
	
	/**************************************************************************
	 *  Action Listener.
	 *  @param e event
	 */
	public void actionPerformed(ActionEvent e)
	{
		log.config("");
		//	Transfer
		if (e.getSource().equals(transferButton))
		{
			transferButton.setEnabled(false);
			saveData();
			loadBPartner();
		}
		//---Aslanbek
		else if (e.getSource().equals(selectAll)){
			loadBPartner();
		}
		else if (e.getActionCommand().equals("comboBoxChanged")){
			
			System.out.println("Location selected!");
			m_New_A_Location_ID = (Integer)locationSearch.getValue();
		}
		//---
	}   //  actionPerformed
	

	/**
	 *  Table Model Listener.
	 *  - Recalculate Totals
	 *  @param e event
	 */
	public void tableChanged(TableModelEvent e)
	{
		boolean isUpdate = (e.getType() == TableModelEvent.UPDATE);
		//  Not a table update
		if (!isUpdate)
		{
			calculate();
			return;
		}
		calculate();
	}   //  tableChanged

	/**
	 *  Vetoable Change Listener.
	 *  - Business Partner
	 * 	- Date
	 *  @param e event
	 */
	public void vetoableChange (PropertyChangeEvent e)
	{
		String name = e.getPropertyName();
		Object value = e.getNewValue();
		log.config(name + "=" + value);
		
		if (value == null)
			return;
		
		// Organization
		if (name.equals("AD_Org_ID"))
		{
			m_AD_Org_ID = ((Integer) value).intValue();
			loadBPartner();
		}
		//  BPartner
		else if (name.equals("C_BPartnerSR_ID"))
		{
			bpartnerSearch.setValue(value);
			m_C_BPartner_ID = ((Integer)value).intValue();
			loadBPartner();
		}
		else if (name.equals("C_BPartnerSR2_ID"))
		{
			bpartner2Search.setValue(value);
			m_C_BPartner2_ID = ((Integer)value).intValue();
			Env.setContext(Env.getCtx(), m_WindowNo, "C_BPartnerSR_ID", m_C_BPartner2_ID);
			if ((total > 0)&&(m_C_BPartner_ID>0)&&(m_C_BPartner2_ID>0)
					   &&(m_C_BPartner_ID!=m_C_BPartner2_ID))
				transferButton.setEnabled(true);
			else
				transferButton.setEnabled(false);
		}
		//	Transfer Date 
		else if (name.equals("Date")) {
			if ((m_C_BPartner_ID>0)&&(m_AD_Org_ID>0)) loadBPartner();
			transferDate = (Timestamp)dateField.getValue();
		} // Document Number	
		else if (name.equals("DocumentNo")) {
			String sql = "SELECT Name FROM HRM_Order" 
					  +" WHERE HRM_OrderType = '1'"
					  +" AND HRM_Number = '"+value+"'"
					  +" AND HRM_Order_ID IN" 
						+" (  SELECT HRM_Order_ID FROM HRM_Employee"
							+" WHERE C_BPartner_ID = "+m_C_BPartner_ID+")";
	        PreparedStatement pstmt = null;
	        ResultSet rs = null;
	        String Description = null;
				try
				{
					pstmt = DB.prepareStatement(sql, null);
					rs = pstmt.executeQuery();
					while (rs.next())
							Description = rs.getString(1);
				}
				catch (SQLException ee)
				{
					log.log(Level.SEVERE, sql, ee);
				}
				finally {
					DB.close(rs, pstmt);
					rs = null; pstmt = null;
				}
			if(Description == null)
				Description="";
			descriptionField.setValue(Description);
		}
	}   //  vetoableChange
	
	public Vector<Vector<Object>> getAssetData(Object date)
	{		
		/********************************
		 *  Load Assets
		 *      1-A_Asset_ID, 2-Value, 3-Name, 4-Description,)
		 *      5-ServiceDate, 6-Locator
		 */
		Vector<Vector<Object>> data = new Vector<Vector<Object>>();
		StringBuffer sql = new StringBuffer(
			  "SELECT a.A_Asset_ID, a.Value, a.Name, a.Description, a.AssetServiceDate"
			+   ", (SELECT Value FROM M_Locator WHERE M_Locator_ID = a.M_Locator_ID), l.name AS A_Location, a.LocationComment "
			+ " FROM ( SELECT i1.A_Asset_ID "
			       + " FROM A_InternalMovement as i1"
			       + " WHERE i1.C_BPartnerSR_ID = "+ m_C_BPartner_ID
			          +" AND i1.DateMoved <= "+DB.TO_DATE((Timestamp)date, true)
			          +" AND i1.DateMoved > COALESCE(" 
			          + " ( SELECT MAX(DateMoved) FROM A_InternalMovement as i2"
			            + " WHERE i2.A_Asset_ID=i1.A_Asset_ID"
			              + " AND i2.C_BPartnerSR_ID <>i1.C_BPartnerSR_ID " +
			              "   AND DateMoved <=" +DB.TO_DATE((Timestamp)date, true)
			              + " ), TO_DATE('1/1/1','YYYY/MM/DD'))"
			            + " GROUP BY i1.A_Asset_ID" 		  
  			  +   " ) AS im"		
			+" LEFT JOIN A_Asset AS a ON a.A_Asset_ID = im.A_Asset_ID " +
			" LEFT JOIN A_Location l ON a.A_Location_ID = l.A_location_ID");
		if (m_AD_Org_ID != 0 )
			sql.append(" AND a.AD_Org_ID=" + m_AD_Org_ID);
		sql.append(" ORDER BY a.Value");
		
		// role security
		//sql = new StringBuffer( MRole.getDefault(Env.getCtx(), false).addAccessSQL( sql.toString(), "p", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO ) );
		
		log.fine("SQL=" + sql.toString());
		try
		{
			PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
			ResultSet rs = pstmt.executeQuery();
			while (rs.next())
			{
				Vector<Object> line = new Vector<Object>();
				line.add((selectAll.getValue()));       //  0-Selection     modify by Aslanbek    old value line.add(new Boolean(true));
				KeyNamePair pp = new KeyNamePair(rs.getInt(1), rs.getString(2));
				line.add(pp);                       //  1-2-A_Asset_ID,Value
				line.add(rs.getString(3));       	//  3-Name
				line.add(rs.getString(4));       	//  4-Description
				line.add(rs.getTimestamp(5));       //  5-ServiceDate
				line.add(rs.getString(6));       	//  6-Locator
				line.add(rs.getString(7)); 			//  7-Location of Asset
				line.add(rs.getString(8));			//  8-Location Comment
				data.add(line);
			}
			rs.close();
			pstmt.close();
		}
		catch (SQLException e)
		{
			log.log(Level.SEVERE, sql.toString(), e);
		}
		return data;
	}

	public void loadBPartner()
	{
		docNoSearch.setValue(null);
		descriptionField.setValue(null);
		Vector<Vector<Object>> data = null;
		if ((m_C_BPartner_ID>0)&&(m_AD_Org_ID>0)) 
			data=getAssetData(dateField.getValue());
		Vector<String> columnNames = new Vector<String>();
		columnNames.add(Msg.getMsg(Env.getCtx(), "Select"));
		columnNames.add("Инвентарный номер");
		columnNames.add(Util.cleanAmp(Msg.translate(Env.getCtx(), "Name")));
		columnNames.add(Msg.getMsg(Env.getCtx(), "Description"));
		columnNames.add("Начало эксплуатации"); ///columnNames.add(Msg.translate(Env.getCtx(), "ServiceDate"));
		columnNames.add("МОЛ");
		columnNames.add("Местоположение");
		columnNames.add("Примечание к местоположению");
		
		//  Remove previous listeners
		assetTable.getModel().removeTableModelListener(this);
		//  Set Model
		DefaultTableModel modelP = new DefaultTableModel(data, columnNames);
		modelP.addTableModelListener(this);
		assetTable.setModel(modelP);
		
		int i = 0;
		assetTable.setColumnClass(i++, Boolean.class, false);    	//  0-Selection
		assetTable.setColumnClass(i++, String.class, true);       	//  1-Value
		assetTable.setColumnClass(i++, String.class, true);         //  2-Name
		assetTable.setColumnClass(i++, String.class, true);       	//  3-Description
		assetTable.setColumnClass(i++, Timestamp.class, true);   	//  4-ServiceDate
		assetTable.setColumnClass(i++, String.class, true);       	//  5-Locator
		assetTable.setColumnClass(i++, String.class, true);			//  6-Location of Asset
		assetTable.setColumnClass(i++, String.class, true);			//  7-Location Comment
		//  Table UI
		assetTable.autoSize();
		//  Set Model
		DefaultTableModel modelI = new DefaultTableModel(data, columnNames);
		modelI.addTableModelListener(this);
		calculate();
	}
	
	public void calculate()
	{
		total = 0;
		int rows = assetTable.getRowCount();
		
		for (int i = 0; i < rows; i++)
			if (((Boolean)assetTable.getValueAt(i, 0)).booleanValue())
				total++;
		differenceField.setText(String.valueOf(total));
		
		if ((total > 0)&&(m_C_BPartner_ID>0)&&(m_C_BPartner2_ID>0)
		   &&(m_C_BPartner_ID!=m_C_BPartner2_ID))
			transferButton.setEnabled(true);
		else
			transferButton.setEnabled(false);
	}
	
	/**************************************************************************
	 *  Save Data
	 */
	public void saveData()
	{
		//  fixed fields
		int AD_Client_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "AD_Client_ID"); 
		if (m_AD_Org_ID == 0)
		{
			ADialog.error(m_WindowNo, panel, "Org0NotAllowed", "");
			throw new AdempiereException("@Org0NotAllowed@");
		}
		//
		log.config("Client=" + AD_Client_ID + ", Org=" + m_AD_Org_ID
			+ ", BPartner=" + m_C_BPartner_ID + ", Date=" + transferDate);

		//  Payment - Loop and add them to paymentList/amountList
		int pRows = assetTable.getRowCount();
		int A_Asset_ID=0;
		int result=0;
		int transfered=0;
		ArrayList<Integer> assetList = new ArrayList<Integer>(pRows);
		//ArrayList<BigDecimal> amountList = new ArrayList<BigDecimal>(pRows);
		//BigDecimal paymentAppliedAmt = Env.ZERO;
		for (int i = 0; i < pRows; i++)
		{
			//  Payment line is selected
			if (((Boolean)assetTable.getValueAt(i, 0)).booleanValue())
			{
				KeyNamePair pp = (KeyNamePair)assetTable.getValueAt(i, 1);   //  Value
				//  Payment variables
				A_Asset_ID = pp.getKey();
				assetList.add(new Integer(A_Asset_ID));
				X_A_Asset asset = new X_A_Asset (Env.getCtx(), A_Asset_ID, null);
				
				if(m_New_A_Location_ID == 0){
					result = asset.TransferTo((String)docNoSearch.getValue(),
							transferDate, m_C_BPartner2_ID,(String)descriptionField.getValue(),asset.getA_Location_ID());
				}
				else{
					result = asset.TransferTo((String)docNoSearch.getValue(),
							transferDate, m_C_BPartner2_ID,(String)descriptionField.getValue(),m_New_A_Location_ID);
				}
				
				if (result>0) transfered++;
				//
				log.fine("A_Asset_ID="+A_Asset_ID+" - Result="+result);
			}
		}
		log.config("Number of Assets=" + assetList.size() + " - Total transfered="+transfered);
		statusBar.setStatusLine("Перемещено основных средств: "+transfered);
		if (transfered>0) {
			//	Prepare Process
			int AD_Process_ID = MProcess.getProcess_ID(repName, Trx.createTrxName());
			MPInstance instance = new MPInstance(Env.getCtx(), AD_Process_ID, 0);
			if (!instance.save())
			{
				log.severe(Msg.getMsg(Env.getCtx(), "ProcessNoInstance"));
			}
			ProcessInfo pi = new ProcessInfo ("", AD_Process_ID);
			pi.setAD_PInstance_ID (instance.getAD_PInstance_ID());
			// Create instance parameters. I e the parameters you want to send to the process.
			ProcessInfoParameter pi1 = new ProcessInfoParameter("AD_Org_ID", m_AD_Org_ID, "","","");
			ProcessInfoParameter pi2 = new ProcessInfoParameter("A_Asset_ID", A_Asset_ID, "","",""); 
			ProcessInfoParameter pi3 = new ProcessInfoParameter("A_InternalMovement_ID", result, "","","");
			pi.setParameter(new ProcessInfoParameter[] {pi1, pi2, pi3});
			Trx trx = Trx.get(Trx.createTrxName(), true);	//trx needs to be committed too

			//	Execute Process
			ProcessCtl worker = new ProcessCtl(null, 0, pi, trx);
			worker.start();     //  complete tasks in unlockUI / generateShipments_complete
		}
	}   //  saveData
	
}